﻿using System.Collections.Generic;
using System;

namespace St0rm.IRCPro.Client {

    /// <summary>
    /// Contains information on a connected server
    /// </summary>
    public class ServerInfo {


        private string _prefix;
        private IDictionary<char, char> _prefixdict = new Dictionary<char, char>();
        private IDictionary<char, char> _modedict = new Dictionary<char, char>();
        private char[] _prefixes;
        private char[] _modes;


        private int _oplevel = 0;
        private int _voicelevel = 0;

        /// <summary>
        /// Name of the server as declared by the server
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// Name of the network as declared by the server
        /// </summary>
        public string Network { get; set; }
        /// <summary>
        /// IP of the server
        /// </summary>
        public string IP { get; set; }
        /// <summary>
        /// PREFIX from RPL_ISSUPPORT
        /// </summary>
        public string Prefix
        {
            get
            {
                return _prefix;
            }
            set
            {
                _prefix = value;
                string modes = value.Substring(1, value.IndexOf(')') -1);
                string prefixes = value.Substring(value.IndexOf(')') + 1);
                lock (_prefixdict)
                {
                    _prefixdict.Clear();
                    for (int i = 0; i < modes.Length; i++)
                    {
                        _prefixdict.Add(prefixes[i], modes[i]);

                        switch (prefixes[i])
                        {
                            case '@':
                                _oplevel = prefixes.Length - i;
                                break;
                            case '+':
                                _voicelevel = prefixes.Length - i;
                                break;
                        }
                    }
                }

                lock (_modedict)
                {
                    _modedict.Clear();
                    for (int i = 0; i < modes.Length; i++)
                    {
                        _modedict.Add(modes[i], prefixes[i]);
                    }
                }

                _prefixes = prefixes.ToCharArray();
                _modes = modes.ToCharArray();
            }
        }
    
        /// <summary>
        /// Channel modes from RPL_ISSUPPORT
        /// </summary>
        public string Chanmodes
        {
            get;
            set;
        }

        /// <summary>
        /// Returns the int level for operators on this server, given that @ is the prefix
        /// </summary>
        public int OpLevel
        {
            get
            {
                return _oplevel;
            }
        }

         /// <summary>
        /// Returns the int level for voiced users on this server, given that + is the prefix
        /// </summary>
        public int VoiceLevel
        {
            get
            {
                return _voicelevel;
            }
        }

        /// <summary>
        /// Returns a char array of the supported prefixes on the server
        /// </summary>
        public char[] Prefixes
        {
            get
            {
                return _prefixes;
            }
        }


        /// <summary>
        /// Returns a char array of the supported modes on the server
        /// </summary>
        public char[] Modes
        {
            get
            {
                return _modes;
            }
        }

        public ServerInfo()
        {
            Prefix = "(ov)@+";
        }

        /// <summary>
        /// Looks the mode that correspondes to the given prefix
        /// </summary>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public char GetModeByPrefix(char prefix)
        {
            char m;
            if (_prefixdict.TryGetValue(prefix, out m))
                return m;
            else
                return '\0';
        }

        /// <summary>
        /// Looks up the prefix that corresponds to the given mode
        /// </summary>
        /// <param name="mode"></param>
        /// <returns></returns>
        public char GetPrefixByMode(char mode)
        {
            char m;
            if (_modedict.TryGetValue(mode, out m))
                return m;
            else
                return '\0';
        }

    }

}
